package com.hyt.it.ogt.kq.service.gov.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hyt.core.util.StringUtils;
import com.hyt.core.util.UUIDUtils;
import com.hyt.it.ogt.kq.common.config.ConfigManager;
import com.hyt.it.ogt.kq.common.config.exception.KqException;
import com.hyt.it.ogt.kq.common.gov.constant.CodeEnum;
import com.hyt.it.ogt.kq.common.gov.constant.ResponseCode;
import com.hyt.it.ogt.kq.service.gov.mapper.OfficeCodeMapper;
import com.hyt.it.ogt.kq.service.gov.model.entity.OfficeArea;
import com.hyt.it.ogt.kq.service.gov.model.entity.OfficeBreakRuleBehavior;
import com.hyt.it.ogt.kq.service.gov.model.entity.OfficeBreakRuleScheme;
import com.hyt.it.ogt.kq.service.gov.model.entity.OfficeCode;
import com.hyt.it.ogt.kq.service.gov.model.entity.OfficeExamAgreement;
import com.hyt.it.ogt.kq.service.gov.model.entity.OfficeTaskConfig;
import com.hyt.it.ogt.kq.service.gov.model.entity.OfficeTaskExamSysConfig;
import com.hyt.it.ogt.kq.service.gov.model.entity.SysArea;
import com.hyt.it.ogt.kq.service.gov.service.IOfficeAreaService;
import com.hyt.it.ogt.kq.service.gov.service.IOfficeBreakRuleBehaviorService;
import com.hyt.it.ogt.kq.service.gov.service.IOfficeBreakRuleSchemeService;
import com.hyt.it.ogt.kq.service.gov.service.IOfficeCodeService;
import com.hyt.it.ogt.kq.service.gov.service.IOfficeExamAgreementService;
import com.hyt.it.ogt.kq.service.gov.service.IOfficeService;
import com.hyt.it.ogt.kq.service.gov.service.IOfficeTaskConfigService;
import com.hyt.it.ogt.kq.service.gov.service.IOfficeTaskExamSysConfigService;
import com.hyt.it.ogt.kq.service.gov.service.ISysAreaService;

/**
 * <p>
 * 机构 服务实现类
 * </p>
 *
 * @author huangyh
 * @since 2021-04-06
 */
@Service
public class OfficeServiceImpl implements IOfficeService {

    @Autowired
    private OfficeCodeMapper officeCodeMapper;

    @Autowired
    private IOfficeCodeService iOfficeCodeService;

    @Autowired
    private ISysAreaService iSysAreaService;

    @Autowired
    private IOfficeAreaService iOfficeAreaService;

    @Autowired
    private IOfficeExamAgreementService iOfficeExamAgreementService;

    @Autowired
    private IOfficeBreakRuleSchemeService iOfficeBreakRuleSchemeService;

    @Autowired
    private IOfficeBreakRuleBehaviorService iOfficeBreakRuleBehaviorService;

    @Autowired
    private IOfficeTaskConfigService iOfficeTaskBehaviorConfigService;

    @Autowired
    private IOfficeTaskExamSysConfigService iOfficeTaskExamSysConfigService;

    @Autowired
    private ConfigManager configManager;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void initOfficeData(String officeId) throws KqException {
        //检查机构是否已经初始化过数据，防止重复初始化
        this.checkInit(officeId);
        //初始化机构系统编码
        this.initOfficeCode(officeId);
        //初始化行政区划
        this.initArea(officeId);
        //初始化行为分析数据
        this.initBehaviorConfig(officeId);
        //初始化考试系统配置数据
        this.initExamSysConfig(officeId);
        //初始化考试协议
        this.initExamAgreement(officeId);
        //初始化违纪处理信息
        this.initBreakRuleScheme(officeId);
        //初始化违纪行为信息
        this.initBreakRuleBehavior(officeId);
    }

    /**
     * 检查机构是否已经初始化过数据
     * @param officeId 机构id
     * @throws KqException 机构已经初始化过数据，抛出异常
     */
    private void checkInit(String officeId) throws KqException {
        //获取机构编码信息
        QueryWrapper<OfficeCode> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(OfficeCode::getOfficeId, officeId)
                .eq(OfficeCode::getDelFlag, false);
        OfficeCode officeCode = iOfficeCodeService.getOne(queryWrapper);
        //检查是否已经初始化过
        if (!ObjectUtils.isEmpty(officeCode)) {
            //当前机构已经初始化过数据
            throw new KqException(ResponseCode.ORGANIZATION_INIT_DATA_EXIST.getCode(),
                    ResponseCode.ORGANIZATION_INIT_DATA_EXIST.getMsg());
        }
    }

    /**
     * 初始化机构系统编码
     * @param officeId 机构id
     * @throws KqException 异常
     */
    private void initOfficeCode(String officeId) throws KqException {
        //获取最大系统编码
        String maxCode = officeCodeMapper.getMaxCode();
        OfficeCode officeCode = new OfficeCode();
        if (StringUtils.isEmpty(maxCode)) {
            //暂无机构开通政企考务，使用默认系统编码
            officeCode.setCode(configManager.getDefaultOfficeCode());
        } else {
            //已有用户开通政企考务，使用最大系统编码生成新的系统编码
            int intCode = Integer.parseInt(maxCode) + 1;
            String code = String.valueOf(intCode);
            officeCode.setCode(code);
        }
        //设置机构id
        officeCode.setOfficeId(officeId);
        //插入系统编码表
        if (!iOfficeCodeService.save(officeCode)) {
            throw new KqException(ResponseCode.ORGANIZATION_INIT_EXCEPTION.getCode(),
                    ResponseCode.ORGANIZATION_INIT_EXCEPTION.getMsg());
        }
    }

    /**
     * 初始化行政区划
     * @param officeId 机构id
     * @throws KqException 异常
     */
    private void initArea(String officeId) throws KqException {
        //获取系统行政区划数据
        QueryWrapper<SysArea> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysArea::getDelFlag, false);
        List<SysArea> sysAreaList = iSysAreaService.list(queryWrapper);
        if (CollectionUtils.isEmpty(sysAreaList)) {
            //未配置系统级行政区划数据
            throw new KqException(ResponseCode.ORGANIZATION_AREA_UN_DIVIDE.getCode(),
                    ResponseCode.ORGANIZATION_AREA_UN_DIVIDE.getMsg());
        }
        //设置主键id及机构id
        List<OfficeArea> officeAreaList = new ArrayList<>();
        for (SysArea sysArea : sysAreaList) {
            OfficeArea officeArea = new OfficeArea();
            BeanUtils.copyProperties(sysArea, officeArea);
            officeArea.setOfficeId(officeId).setId(UUIDUtils.newSortUUID());
            officeAreaList.add(officeArea);
        }
        //插入行政区划表
        int batchSize = 4000;
        if (!iOfficeAreaService.saveBatch(officeAreaList, batchSize)) {
            throw new KqException(ResponseCode.ORGANIZATION_INIT_EXCEPTION.getCode(),
                    ResponseCode.ORGANIZATION_INIT_EXCEPTION.getMsg());
        }
    }

    /**
     * 初始化考试协议
     * @param officeId 机构id
     * @throws KqException 异常
     */
    private void initExamAgreement(String officeId) throws KqException {
        //获取系统级考试协议数据
        QueryWrapper<OfficeExamAgreement> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(OfficeExamAgreement::getLevel, CodeEnum.SYSTEM_DATA.getCode())
                .eq(OfficeExamAgreement::getDelFlag, false);
        List<OfficeExamAgreement> officeExamAgreementList = iOfficeExamAgreementService.list(queryWrapper);
        if (CollectionUtils.isEmpty(officeExamAgreementList)) {
            //未配置系统级考试协议数据
            throw new KqException(ResponseCode.ORGANIZATION_NOT_CONFIGURED_TREATY_DATA.getCode(),
                    ResponseCode.ORGANIZATION_NOT_CONFIGURED_TREATY_DATA.getMsg());
        }
        //生成机构级考试协议数据
        officeExamAgreementList.forEach(agreement -> agreement.setLevel(2)
                .setOfficeId(officeId)
                .setId(UUIDUtils.newSortUUID()));
        //插入系统级与机构级考试协议表
        if (!iOfficeExamAgreementService.saveBatch(officeExamAgreementList)) {
            throw new KqException(ResponseCode.ORGANIZATION_INIT_EXCEPTION.getCode(),
                    ResponseCode.ORGANIZATION_INIT_EXCEPTION.getMsg());
        }
    }

    /**
     * 初始化违纪处理信息
     * @param officeId 机构id
     * @throws KqException 异常
     */
    private void initBreakRuleScheme(String officeId) throws KqException {
        //获取系统级违纪处理数据
        QueryWrapper<OfficeBreakRuleScheme> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(OfficeBreakRuleScheme::getLevel, CodeEnum.SYSTEM_DATA.getCode())
                .eq(OfficeBreakRuleScheme::getDelFlag, false);
        List<OfficeBreakRuleScheme> officeBreakRuleSchemeList = iOfficeBreakRuleSchemeService.list(queryWrapper);
        if (CollectionUtils.isEmpty(officeBreakRuleSchemeList)) {
            //未配置系统级违纪处理数据
            throw new KqException(ResponseCode.ORGANIZATION_NOT_CONFIGURED_VIOLATION_HAND_DATA.getCode(),
                    ResponseCode.ORGANIZATION_NOT_CONFIGURED_VIOLATION_HAND_DATA.getMsg());
        }
        //生成机构级违纪处理数据
        officeBreakRuleSchemeList.forEach(scheme -> scheme.setLevel(CodeEnum.OFFICE_DATA.getCode())
                .setOfficeId(officeId)
                .setId(UUIDUtils.newSortUUID()));
        //插入系统级与机构级违纪处理表
        if (!iOfficeBreakRuleSchemeService.saveBatch(officeBreakRuleSchemeList)) {
            throw new KqException(ResponseCode.ORGANIZATION_INIT_EXCEPTION.getCode(),
                    ResponseCode.ORGANIZATION_INIT_EXCEPTION.getMsg());
        }
    }

    /**
     * 初始化违纪行为信息
     * @param officeId 机构id
     * @throws KqException 异常
     */
    private void initBreakRuleBehavior(String officeId) throws KqException {
        //获取系统级违纪行为数据
        QueryWrapper<OfficeBreakRuleBehavior> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(OfficeBreakRuleBehavior::getLevel, CodeEnum.SYSTEM_DATA.getCode())
                .eq(OfficeBreakRuleBehavior::getDelFlag, false);
        List<OfficeBreakRuleBehavior> officeBreakRuleBehaviorList = iOfficeBreakRuleBehaviorService.list(queryWrapper);
        if (CollectionUtils.isEmpty(officeBreakRuleBehaviorList)) {
            //未配置系统级违纪行为数据
            throw new KqException(ResponseCode.ORGANIZATION_NOT_CONFIGURED_ACTION_DATA.getCode(),
                    ResponseCode.ORGANIZATION_NOT_CONFIGURED_ACTION_DATA.getMsg());
        }
        //生成机构级违纪行为数据
        officeBreakRuleBehaviorList.forEach(behavior -> behavior.setLevel(CodeEnum.OFFICE_DATA.getCode())
                .setOfficeId(officeId)
                .setId(UUIDUtils.newSortUUID()));
        //插入系统级与机构级违纪行为表
        if (!iOfficeBreakRuleBehaviorService.saveBatch(officeBreakRuleBehaviorList)) {
            throw new KqException(ResponseCode.ORGANIZATION_INIT_EXCEPTION.getCode(), "插入系统级与机构级违纪行为表失败");
        }
    }

    /**
     * 初始化行为分析数据
     * @param officeId 机构id
     * @throws KqException 政企考务业务异常
     */
    private void initBehaviorConfig(String officeId) throws KqException {
        //获取系统级行为分析数据
        QueryWrapper<OfficeTaskConfig> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(OfficeTaskConfig::getLevel, CodeEnum.SYSTEM_DATA.getCode())
                .eq(OfficeTaskConfig::getDelFlag, false);
        List<OfficeTaskConfig> officeTaskBehaviorConfigList = iOfficeTaskBehaviorConfigService.list(queryWrapper);
        if (CollectionUtils.isEmpty(officeTaskBehaviorConfigList)) {
            //未配置系统级行为分析数据
            throw new KqException(ResponseCode.ORGANIZATION_NOT_CONFIGURED_VIOLATION_ACTION_REPORT_DATA.getCode(),
                    ResponseCode.ORGANIZATION_NOT_CONFIGURED_VIOLATION_ACTION_REPORT_DATA.getMsg());
        }
        //生成机构级行为分析数据
        officeTaskBehaviorConfigList.forEach(behavior -> behavior.setLevel(CodeEnum.OFFICE_DATA.getCode())
                .setOfficeId(officeId)
                .setId(UUIDUtils.newSortUUID()));
        //插入任务行为分析模板表
        if (!iOfficeTaskBehaviorConfigService.saveBatch(officeTaskBehaviorConfigList)) {
            //插入任务行为分析模板表失败
            throw new KqException(ResponseCode.ORGANIZATION_INIT_EXCEPTION.getCode(), "插入任务行为分析模板表失败");
        }
    }

    /**
     * 初始化考试系统配置数据
     * @param officeId 机构id
     * @throws KqException 异常
     */
    private void initExamSysConfig(String officeId) throws KqException {
        //获取系统级考试系统配置数据
        QueryWrapper<OfficeTaskExamSysConfig> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(OfficeTaskExamSysConfig::getLevel, CodeEnum.SYSTEM_DATA.getCode())
                .eq(OfficeTaskExamSysConfig::getDelFlag, false);
        List<OfficeTaskExamSysConfig> officeTaskExamSysConfigList = iOfficeTaskExamSysConfigService.list(queryWrapper);
        if (CollectionUtils.isEmpty(officeTaskExamSysConfigList)) {
            //未配置系统级考试系统配置数据
            throw new KqException(ResponseCode.ORGANIZATION_NOT_CONFIGURED_TASK_DATA.getCode(),
                    ResponseCode.ORGANIZATION_NOT_CONFIGURED_TASK_DATA.getMsg());
        }
        //生成机构级考试系统配置数据
        officeTaskExamSysConfigList.forEach(config -> config.setLevel(CodeEnum.OFFICE_DATA.getCode())
                .setOfficeId(officeId)
                .setId(UUIDUtils.newSortUUID()));
        //插入任务考试系统配置模板表
        if (!iOfficeTaskExamSysConfigService.saveBatch(officeTaskExamSysConfigList)) {
            //插入任务考试系统配置模板表失败
            throw new KqException(ResponseCode.ORGANIZATION_INIT_EXCEPTION.getCode(),
                    ResponseCode.ORGANIZATION_INIT_EXCEPTION.getMsg());
        }
    }

}
